<!DOCTYPE html>
<html lang="en">

  <head>

<!-- AdThrive Head Tag Manual -->
<script data-no-optimize="1" data-cfasync="false">
(function(w, d) {
	w.adthrive = w.adthrive || {};
	w.adthrive.cmd = w.
	adthrive.cmd || [];
	w.adthrive.plugin = 'adthrive-ads-manual';
	w.adthrive.host = 'ads.adthrive.com';var s = d.createElement('script');
	s.async = true;
	s.referrerpolicy='no-referrer-when-downgrade';
	s.src = 'https://' + w.adthrive.host + '/sites/643436a4e6d20859e40a446b/ads.min.js?referrer=' + w.encodeURIComponent(w.location.href) + '&cb=' + (Math.floor(Math.random() * 100) + 1);
	var n = d.getElementsByTagName('script')[0];
	n.parentNode.insertBefore(s, n);
})(window, document);
</script>
<!-- End of AdThrive Head Tag -->





    <!-- Global site tag (gtag.js) - Google Analytics -->



  <script async src="https://www.googletagmanager.com/gtag/js?id=UA-79254642-6"></script>

    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', 'UA-79254642-6');
    </script>

    <meta charset="utf-8">
    <title>Responsive charts with d3.js</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="This post describes several techniques allowing to turn your d3.js graph responsive.">
    <meta name="keywords" content="Data,Dataviz,Datavisualization,Javascript, JS, d3.js, shapes, responsiveness">
    <meta name="author" content="Yan Holtz">
  <link rel="icon" href="../img/logo/D3_single_small.png">

    <meta property="og:title" content="Responsive charts with d3.js<">
    <meta property="og:image" content="img/overview_RGG.png">
    <meta property="og:description" content="This post describes several techniques allowing to turn your d3.js graph responsive.">

    <!-- Bootstrap core CSS -->
    <link href="../vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom fonts for this template -->
    <link href="../vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

    <!-- Custom styles for this template -->
    <link href="../css/agency.css" rel="stylesheet">

    <!-- PRISM -->
    <script src="../LIB/prism.js"></script>
    <link href="../LIB/prism.css" rel="stylesheet" />

    <!-- D3.JS v4 -->
    <script src="../js/d3.v4.js"></script>

    <!-- JQUERY -->
    <script src="../vendor/jquery/jquery.min.js"></script>

    <!-- HTML TO CANVAS -->
    <script src="../js/html2canvas.js"></script>

    <!-- Function to parse html and js code chunks made by Yan Holtz -->
    <script src="../js/myParser.js"></script>

    <!-- Bootstrap js -->
    <script src="../vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
    <script src="../js/agency.min.js"></script>

  </head>




  <body data-spy="scroll" data-target="#myScrollspy" data-offset="1">


    <!-- THIS ALLOWS TO INSERT THE MENU THAT IS STORED IN A MENU.HTML FILE-->
    <nav class="navbar navbar-expand-lg fixed-top" id="mainNav"></nav>
    <script>
    $(function(){
      $("#mainNav").load("../html_chunk/menu.html");
    });
    </script>

    <!-- THIS ALLOWS TO INSERT THE MODAL OF THE MENU THAT IS STORED IN A MENU_MODAL.HTML FILE-->
    <div id="modal_menu_insertion"> </div>
    <script>
    $(function(){
      $("#modal_menu_insertion").load("../html_chunk/menu_modal.html");
    });
    </script>




    <!-- Header -->
    <header class="masthead" style="padding-top: 150px; padding-bottom: 80px">
      <div class="textlanding">
          <h1>Responsive charts with d3.js</h1>
          <hr class="short_hr">
          <br>
          <ul class="list-inline social-buttons">
            <li class="list-inline-item">
              <a href="https://twitter.com/R_Graph_Gallery">
                <i class="fa fa-twitter"></i>
              </a>
            </li>
            <li class="list-inline-item social-buttons">
              <a href="https://github.com/holtzy">
                <i class="fa fa-github" style="color: white"></i>
              </a>
            </li>
            <li class="list-inline-item social-buttons">
              <a href="https://www.linkedin.com/in/yan-holtz-2477534a/">
                <i class="fa fa-linkedin"></i>
              </a>
            </li>
          </ul>
          <br><br>
          <p style="max-width: 700px; margin: auto">Like every other element of a webpage, charts deserve to be <u>responsive</u>: their size must adapt to the <u>device size</u>. This post describes several approaches allowing to get this feature for d3.js charts.</p>
      </div>
    </header>






    <!-- TABLE of CONTENT -->
    <div>
        <nav class="col-sm-3 col-4" id="myScrollspy">
          <ul class="nav nav-pills flex-column">
            <li class="nav-item">
              <a class="nav-link" href="#basic">Most Basic</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#application">Area chart</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#performance">Debouncing</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#bootstrap">Bootstrap columns</a>
            </li>
          </ul>
        </nav>
    </div>















<!-- ==================== BASIC RESIZING ==================== -->

<section class="bg" id="basic">
<div class="container" >
  <h1>Most basic example</h1>
  <hr>
  <p>A common pattern to make a chart responsive:</p>
  <ul>
    <li>Recover the current div <code>width</code> with this piece of code: <code>parseInt(d3.select('#my_dataviz').style('width'), 10)</code></li>
    <li>A function that draws a chart for a specific <code>width</code> is created</li>
    <li>An event listener will run this function each time the <code>div</code> size changes</li>
  </ul>
  <br>
  <div class="bg-light" id="res-basicResize" ></div>




<!-- ==================== CODE SECTION = WHERE THE CODE APPEARS ==================== -->
<div class="col-lg-12">

<!-- ========= show html code ============== -->
<aside style="position: -webkit-sticky; position: sticky; top: 120px">&larr; Edit me! </aside>
<pre class="language-html"><code id="html-basicResize" contenteditable="true"><xmp><!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the chart will take place -->
<div id="div_basicResize"></div>

</xmp></code></pre>
<!-- ==================================== -->



<!-- ========= show JS code ==============  -->
<pre class="language-js"><code id="js-basicResize" contenteditable="true"><xmp><script>

// Initialize a SVG area. Note that the width is not specified yet, since unknown
var Svg = d3.select("#div_basicResize")
  .append("svg")
  .attr("height", 200)

// Create dummy data
var data = [19, 13, 54, 78, 98, 120, 138]

// Add X axis. Note that we don't know the range yet, so we cannot draw it.
var x = d3.scaleLinear()
  .domain([0, 150])
var xAxis = Svg.append("g")
  .attr("transform", "translate(0,150)")

// Initialize circles. Note that the X scale is not available yet, so we cannot draw them
var myCircles = Svg
  .selectAll("circles")
  .data(data)
  .enter()
  .append("circle")
    .style("fill", "#69b2b3")
    .attr("r", 20)
    .attr("cy", 100)



// A function that finishes to draw the chart for a specific device size.
function drawChart() {

  // get the current width of the div where the chart appear, and attribute it to Svg
  currentWidth = parseInt(d3.select('#div_basicResize').style('width'), 10)
  Svg.attr("width", currentWidth)

  // Update the X scale and Axis (here the 20 is just to have a bit of margin)
  x.range([ 20, currentWidth-20 ]);
  xAxis.call(d3.axisBottom(x))

  // Add the last information needed for the circles: their X position
  myCircles
    .attr("cx", function(d){ return x(d)})
  }


// Initialize the chart
drawChart()

// Add an event listener that run the function when dimension change
window.addEventListener('resize', drawChart );


</script></xmp></code></pre>
<!-- ==================================== -->







    <!-- ==================== JAVASCRIPT SECTION : EXECUTE THIS CODE AND MAKE IT INTERACTIVE ==================== -->
    <script>
    // At the beginning, I read the html and JS fragments
    myHtmlParser('html-basicResize', 'res-basicResize')
    myJSParser('js-basicResize', 'res-basicResize')

    // If the user change the JS fragment, I run it again:
    document.getElementById('js-basicResize').addEventListener("input", function() {
    d3.select('#res-basicResize').html("");
    myHtmlParser('html-basicResize', 'res-basicResize');
    myJSParser('js-basicResize', 'res-basicResize');
    })

    // If the user change the HTML fragment, I run it again:
    document.getElementById('html-basicResize').addEventListener("input", function() {
    d3.select('#res-basicResize').html("");
    myHtmlParser('html-basicResize', 'res-basicResize');
    myJSParser('js-basicResize', 'res-basicResize');
    })
    </script>

    </div>


      </div>
    </div>
    </section>
    <br>























  <!-- ==================== APPLICATION ==================== -->

  <section id="application" >
  <div class="container" >
    <h1>Application to an area chart</h1>
    <hr>
    <p>First of all, make sure you understood how this <a href="area_basic.html">basic area chart</a> is built with d3.js. The following example just uses the concept described above to make it responsive. Try to change the window size!</p>
    <div id="my_dataviz"></div>
  </div>
  </section>














<!-- ==================== PERFORMANCE==================== -->

<section class="bg" id="performance">
<div class="container" >

  <h1>Better performance with <code>debouncing</code></h1>
  <hr>
  <p>The most common way to add responsiveness in d3.js is to use an event listener. Here is the basic idea:</p>

</div>
</section>








<!-- ==================== BOOTSTRAP ==================== -->

<section class="bg" id="performance">
<div class="container" >

  <h1>The advantage of bootstrap</h1>
  <hr>
  <p>Using the bootstrap grid as a workaround for responsiveness</p>

</div>
</section>











<!-- ============================ RELATED BLOCKS ============================ -->

<section id="related" class="bg-light" style="padding-top: 70px; padding-bottom: 70px">
  <div class="container">
    <div class="row">
      <div class="col-lg-5 text-center .align-middle" style="border-right: solid; ">
        <div style="display: table; height: 150px; overflow: hidden;">
          <div style="display: table-cell; vertical-align: middle;">
            <h2 class="section-heading text-uppercase" style="color: black">Related blocks</h2>
          </div>
        </div>
      </div>
      <div class="col-lg-5">
        <div style="display: table; height: 150px; overflow: hidden;">
          <div style="display: table-cell; vertical-align: middle;">
            <ul>
            <li><i>Responsive D3js chart - </i>by <a href="https://ablesense.com/blogs/news/responsive-d3js-charts">Derek Morash</a></li>
            <br>
            <li><i>D3.js v4 Example/Tutorial: Responsive Bar Chart - </i>by <a href="https://bl.ocks.org/alanvillalobos/14e9f0d80ea6b0d8083ba95a9d571d13">Alan Villalobos</a></li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>


















<!-- ============================ CONTACT SECTION ============================ -->

<!-- ANCHOR -->
<a name="contactanchor"></a>

<section id="contact" class="bg" style="background-color: white"></section>

<!-- THIS ALLOWS TO INSERT THE CONTACT CHUNK THAT IS STORED IN A CONTACT.HTML FILE-->
<script>
$(function(){
  $("#contact").load("../html_chunk/contact.html");
});
</script>







<!-- ============================ FOOTER SECTION ============================ --><footer class="bg-light" id="myFooter"></footer>

<!-- THIS ALLOWS TO INSERT THE FOOTER THAT IS STORED IN A FOOTER.HTML FILE-->
<script>
$(function(){
  $("#myFooter").load("../html_chunk/footer.html");
});
</script>

<!-- ============================ -->























  </body>

</html>
